//
// Created by admin on 2024/8/2.
//

#ifndef _CIRCULARBUFFER_H
#define _CIRCULARBUFFER_H

#include <string.h>
#include <stdint.h>
#include "stddef.h"


class CircularBuffer {
public:
	typedef struct {
		size_t   head;     /** linked list head */
		size_t   tail;     /** linked list tail */
		uint32_t overflow; /** Buffer overflow count */
		bool     full;     /** cache full flags */
		bool     pushLock; /** buffer write lock */
		bool     pullLock; /** buffer read lock */
	} Circular_t;

public:
	CircularBuffer(size_t size, bool cover = true);
	CircularBuffer(uint8_t* buf, size_t size, bool cover = true);
	~CircularBuffer();

	/**
	 * Get buffer used space size
	 * @return data written length
	 */
	size_t available();

	size_t push(uint8_t* data, size_t len);
	size_t push(const char* cstr) { return push((uint8_t*)cstr, strlen(cstr)); }
	size_t pull(uint8_t* data, size_t len);
	int    peek();
	size_t pop(size_t len);
	void   flush();

	size_t readToKeyword(const char* key, uint8_t* data, size_t len, size_t start_index = 0);
	size_t readToKeyword(const char* head, const char* tail, uint8_t* data, size_t len);

	/**
	 * Buffer direct write function
	 * Use function in sequence.
	 * 1.push start: pushStart()
	 * 2.get buffer write pointer: head()
	 * 3.get continuous buffer space size: getPushLineSize()
	 * 4.push end, input write size: pushEnd()
	 * */
	void     pushStart();
	uint8_t* head();
	size_t   getPushLineSize();
	void     pushEnd(size_t len);

	/**
	 * Buffer direct read function
	 * Use function in sequence.
	 * */
	void     pullStart();
	uint8_t* tail();
	size_t   getPullLineSize();
	void     pullEnd(size_t len);

	CircularBuffer& operator =(const char* cstr);
	CircularBuffer& operator +=(CircularBuffer& rhs);

	CircularBuffer& operator +=(const char* cstr) {
		push(cstr);
		return *this;
	}

protected:
	uint8_t* buffer;
	size_t   _size;

private:
	bool       _is_static_buf;
	bool       _cover;
	Circular_t ll;
};


#endif //_CIRCULARBUFFER_H
